package com.mrd.gtimp.business.action;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.mrd.constant.MsgConstants;
import com.mrd.exception.QueryException;
import com.mrd.framework.config.web.json.Result;
import com.mrd.framework.config.web.json.annotation.JField;
import com.mrd.framework.config.web.json.annotation.Json;
import com.mrd.framework.ui.Jqgrid;
import com.mrd.framework.ui.filter.SearchRule;
import com.mrd.framework.ui.filter.SearchRuleOption;
import com.mrd.gtimp.business.entity.FundAjustment;
import com.mrd.gtimp.business.service.CommonPaymentBiz;
import com.mrd.gtimp.business.service.FundAjustmentBiz;
import com.mrd.gtimp.business.service.PaymentABCBiz;
import com.mrd.gtimp.v2.fund.FundPayTypeEnum;
import com.mrd.gtimp.v2.fund.FundStateEnum;
import com.mrd.payClient.message.PayMessage;
import com.mrd.util.LoginUtil;
import com.mrd.util.PayProperties;

@Controller
@RequestMapping("/fund")
public class FundAjustmentAction {
  @Resource
  private FundAjustmentBiz biz;
  @Resource
  private PaymentABCBiz paymentABCBiz;
  @Resource
  private CommonPaymentBiz commonPaymentBiz;
  @Resource
  private FundAjustmentBiz fundAjustmentBiz;
  @Resource
  private PayProperties payProperties;

  @RequestMapping("/ajustment-main")
  public String main(Model model) {
    model.addAttribute("allFundState", FundStateEnum.ALL_OPTION());
    model.addAttribute("allFundPayType", FundPayTypeEnum.ALL_OPTION());
    return "/gtimp/fundAjustment/customer_main";
  }

  @RequestMapping("/ajustment-reviewer_main")
  public String reviewer_main(Model model) {
    model.addAttribute("allFundState", FundStateEnum.ALL_OPTION());
    model.addAttribute("allFundPayType", FundPayTypeEnum.ALL_OPTION());
    return "/gtimp/fundAjustment/reviewer_main";
  }

  @RequestMapping("/ajustment-view")
  public String view(Model model, String id) {
    model.addAttribute("id", id);
    model.addAttribute("allFundState", FundStateEnum.ALL_OPTION());
    model.addAttribute("allFundPayType", FundPayTypeEnum.ALL_OPTION());
    return "/gtimp/fundAjustment/customer_edit";
  }

  @RequestMapping("/ajustment-onlinePay")
  public String onlinePay(Model model, String id) {
    model.addAttribute("id", id);
    if (StringUtils.isNotEmpty(id)) {
      try {
        model.addAttribute("fundAjustment", fundAjustmentBiz.findEntityById(id));
      } catch (QueryException e) {
        e.printStackTrace();
      }
    }
    model.addAttribute("allFundState", FundStateEnum.ALL_OPTION());
    model.addAttribute("allFundPayType", FundPayTypeEnum.ALL_OPTION());
    return "/gtimp/fundAjustment/customer_online_pay2";
  }

  // 金额验证，正则校验金额，且小数点只能是2位
  public static boolean isNumber(String str) {
    Pattern pattern = Pattern.compile("^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$"); // 判断小数点后2位的数字的正则表达式
    Matcher match = pattern.matcher(str);
    if (match.matches() == false) {
      return false;
    } else {
      return true;
    }
  }

  @RequestMapping("/getQRcode")
  @ResponseBody
  public PayMessage getQRcode(String payChannel, String orderNo, String totalAmount) {

    if (StringUtils.isEmpty(totalAmount)) {
      return null;
    }
    if (!isNumber(totalAmount)) {
      return null;
    }
    String userKey;
    if (payChannel.equalsIgnoreCase("1")) {
      userKey = payProperties.getWechat(); // 微信的key
    } else if (payChannel.equalsIgnoreCase("2")) {
      userKey = payProperties.getAlipay(); // 支付宝
    } else {
      return null;
    }

    if (StringUtils.isEmpty(orderNo)) {
      orderNo = generatePayId(FundPayTypeEnum.getFundPayTypeEnumByPayChannel(payChannel));
    }

    try {
      return fundAjustmentBiz.getPayPlatformPayMessage(payChannel, userKey, orderNo, totalAmount);
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }

  /**
   * 获取支付平台支付宝在线支付交易地址
   * @param orderNo 交易号
   * @param totalAmount 金额 单位：元
   * @return 封装信息
   */
  @RequestMapping("/getPayPlatformOnlinePayUrl")
  @ResponseBody
  public Result getPayPlatformOnlinePayUrl(String orderNo, String totalAmount) {
    if(StringUtils.isEmpty(totalAmount) || !isNumber(totalAmount)){
      return  Result.newFailInstance("错误的金额");
    }
    if (StringUtils.isEmpty(orderNo)) {
      orderNo = generatePayId(FundPayTypeEnum.Alipay);
    }
    String requestUrl = fundAjustmentBiz.getPayPlatformOnlinePayUrl(payProperties.getAlipay(), orderNo, totalAmount);
    if(requestUrl == null){
      return  Result.newFailInstance("抱歉，平台暂时无法提供支付宝预付款服务");
    }
    return Result.newSuccessInstance("成功获取支付组件支付宝在线支付地址", requestUrl);
  }

  @RequestMapping("/ajustment-reviewer_view")
  public String reviewer_view(Model model, String id) {
    model.addAttribute("id", id);
    model.addAttribute("allFundState", FundStateEnum.ALL_OPTION());
    model.addAttribute("allFundPayType", FundPayTypeEnum.ALL_OPTION());
    return "/gtimp/fundAjustment/reviewer_edit";
  }

  @RequestMapping("/ajustment-findReviewerList")
  @ResponseBody
  @Json({@JField("id"), @JField("bid"), @JField("billNo"), @JField("owner.name"),
      @JField("registrant.account"), @JField("amount"), @JField("fundPayType"), @JField("state"),
      @JField("regDate"), @JField("reviewDate"), @JField("registrant.name"),
      @JField("modifier.name"), @JField("reviewer.name")})
  public Page<FundAjustment> findReviewerList(Jqgrid jqgrid) {
    String comId = LoginUtil.getLoginUser().getCompany().getId();// get from user
    try {
      jqgrid.addRule(
          new SearchRule("fundPayType", SearchRuleOption.ne, FundPayTypeEnum.ONLINE.toString()));
      boolean stateSet = false;
      if (null != jqgrid.getFilters().getRules()) {
        for (SearchRule rule : jqgrid.getFilters().getRules()) {
          if (!StringUtils.isEmpty(rule.getField())
              && rule.getField().toLowerCase().equals("state")) {
            if (null == rule.getData() || rule.getData().toString().toUpperCase().equals("TEMP")) {
              rule.setData(FundStateEnum.INIT.toString());
            } else {
              stateSet = true;
            }
          }
        }
      }
      if (!stateSet) {
        SearchRule rule =
            new SearchRule("state", SearchRuleOption.eq, FundStateEnum.INIT.toString());
        jqgrid.addRule(rule);
      }
      return biz.findByJqgrid(jqgrid);
    } catch (QueryException e) {
      e.printStackTrace();
    }
    return null;
  }

  /**
   * 刷新余额，批量更新在线充值支付中状态的充值记录
   */
  @RequestMapping("/ajustment-refreshFund")
  @ResponseBody
  @Json({@JField("id"), @JField("billNo"), @JField("owner.name"), @JField("amount"),
      @JField("financialType"), @JField("ietype"), @JField("balance"), @JField("regDate")})
  public Page<FundAjustment> refreshFund(Jqgrid jqgrid) {
    SearchRule rule = new SearchRule("owner.id", SearchRuleOption.eq,
        LoginUtil.getLoginUser().getCompany().getId());
    jqgrid.addRule(rule);
    SearchRule rule2 = new SearchRule("state", SearchRuleOption.eq, FundStateEnum.INIT.toString());
    jqgrid.addRule(rule2);
    SearchRule rule3 =
        new SearchRule("fundPayType", SearchRuleOption.eq, FundPayTypeEnum.ONLINE.toString());
    jqgrid.addRule(rule3);
    try {
      Page<FundAjustment> results = biz.findByJqgrid(jqgrid);
      if (null != results) {
        // 这段代码有问题，会导致重复到账
        // for (FundAjustment a : results) {
        // if (paymentABCBiz.queryABCPayStatus(a.getBillNo())) {
        // biz.onlinePaySuccess(a);
        // }
        // }
      }
      return results;
    } catch (QueryException e) {
      e.printStackTrace();
    }
    return null;
  }

  /**
   * 编辑信息
   */
  @RequestMapping("/ajustment-find")
  @ResponseBody
  @Json({@JField("id"), @JField("bid"), @JField("billNo"), @JField("state"), @JField("fundPayType"),
      @JField("amount"), @JField("transferCertificate.id"), @JField("shuiDan"),
      @JField("reviewShuiDan")})
  public FundAjustment find(FundAjustment fundAjustment) {
    if (fundAjustment != null && StringUtils.isNotEmpty(fundAjustment.getId())) {
      try {
        fundAjustment = biz.findEntityById(fundAjustment.getId());
        if (StringUtils.isNotEmpty(fundAjustment.getBillNo())
            && FundPayTypeEnum.ONLINE.toString().equals(fundAjustment.getFundPayType())
            && FundStateEnum.INIT.toString().equals(fundAjustment.getState())) {
          if (paymentABCBiz.queryABCPayStatus(fundAjustment.getBillNo())) {
            biz.onlinePaySuccess(fundAjustment);
          }
        }
        return fundAjustment;
      } catch (QueryException e) {
        e.printStackTrace();
      }
    }
    return null;
  }

  private String generatePayId(String prefix) {
    return prefix + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date())
        + ((int) (Math.random() * 100));
  }

  private String generatePayId(FundPayTypeEnum payTypeEnum) {
    String prefix = "CZP";
    // if(FundPayTypeEnum.ONLINE.equals(payTypeEnum)){
    // prefix = "CZP";
    // }else if(FundPayTypeEnum.Alipay.equals(payTypeEnum)){
    // prefix = "AZP";
    // }else if(FundPayTypeEnum.WechatPay.equals(payTypeEnum)){
    // prefix = "WZP";
    // }
    return generatePayId(prefix);
  }

  /**
   * 格式化double类型数据 #http://blog.163.com/xiaohui_1123@126/blog/static/3980524020105723918367/
   */
  private String roundUp(double d, String RoundFormat) {
    DecimalFormat nf = new DecimalFormat(RoundFormat);
    return nf.format(d);
  }

  private String generatePayUrl(String payId, double fee) {
    return generatePayUrl(payId, "余额预付款", fee);
  }

  private String generatePayUrl(String payId, String title, double fee) {
    Map<String, String> paymentRequestResult =
        paymentABCBiz.requestForPayment(payId, roundUp(fee, "0.00"), title, "6");
    if (paymentRequestResult != null && BusinessAction.KEY_request_result_success
        .endsWith(paymentRequestResult.get(BusinessAction.KEY_request_result))) {
      return paymentRequestResult.get(BusinessAction.KEY_paymentURL);
    } else {
      return "error";
    }
  }

  private String buildJsonStrResult(JSONObject json, String msg) {
    JSONObject jsonObject = buildJsonResult(json, msg);
    return jsonObject == null ? msg : jsonObject.toJSONString();
  }

  private JSONObject buildJsonResult(JSONObject json, String msg) {
    try {
      JSONObject aresult = new JSONObject();// .parseObject(msg);
      aresult.putAll(json);
      aresult.put("msg", msg);
      return aresult;
    } catch (Exception e) {

    }
    return null;
  }

  /**
   * 调用此方法后，必须马上保存fundAjustment，并返回"mgs"
   */
  private String generatePayUrl(FundAjustment fundAjustment) {
    String msg = "";
    // online pay
    if (FundStateEnum.INIT.toString().equals(fundAjustment.getState())
        && FundPayTypeEnum.ONLINE.toString().equals(fundAjustment.getFundPayType())
        && fundAjustment.getAmount() > 0) {
      msg = MsgConstants.SAVE_SUECCES;
      String payId = generatePayId(FundPayTypeEnum.ONLINE);
      String purl = generatePayUrl(payId, fundAjustment.getAmount());
      fundAjustment.setAmount(Double.parseDouble(roundUp(fundAjustment.getAmount(), "0.00")));
      fundAjustment.setBillNo(payId);
      JSONObject json = new JSONObject();
      json.put("purl", purl);
      return buildJsonStrResult(json, msg);
    }
    return msg;
  }

  /**
   * 自动查账jsp页面
   */
  @RequestMapping("/ajustment-sysjob")
  public String sysJob() {
    return "/sysjob/v";
  }

  @RequestMapping("/getPaymentResult")
  @ResponseBody
  public String getPaymentResult(String orderNo) {
    String result = commonPaymentBiz.getPaymentResult(orderNo);
    System.out.println("getPaymentResult: " + result);
    return result;
  }

  @RequestMapping("/paySuccess")
  public String paySuccess() {
    return "/gtimp/fundAjustment/pay_success";
  }


  /**
   * 新增或修改信息
   */
  @RequestMapping("/ajustment-saveOrUpdate")
  @ResponseBody
  public Result saveOrUpdate(FundAjustment fundAjustment) {
    // Map<String, Object> rsData = new HashMap<>();
    Result msg = null;
    try {
      if (StringUtils.isEmpty(fundAjustment.getId())) { // 新增操作
        fundAjustment.setId(null);
        fundAjustment.setOwner(LoginUtil.getLoginUser().getCompany());
        fundAjustment.setRegDate(new Date());
        fundAjustment.setRegistrant(LoginUtil.getLoginUser());
        // fundAjustment.setFundPayType(FundPayTypeEnum.ONLINE.toString());
        fundAjustment.setBid(fundAjustment.generateBid());
        if (null == fundAjustment.getState()) {
          fundAjustment.setState(FundStateEnum.TEMP.toString());
        } else if (!FundStateEnum.TEMP.toString().equals(fundAjustment.getState())
            && !FundStateEnum.INIT.toString().equals(fundAjustment.getState())) {
          msg = Result.newFailInstance(
              MsgConstants.SAVE_FAIL + "invalid state=" + fundAjustment.getState());
          return msg;
        }
        // online pay
        Object purl = generatePayUrl(fundAjustment);
        biz.saveOrupdateEntity(fundAjustment);
        return Result.newSuccessInstance(MsgConstants.SAVE_SUECCES, purl);
      } else { // 修改操作
        if (FundStateEnum.SUCCESS.toString().equals(fundAjustment.getState())) {
          // review pass
          fundAjustment.setReviewer(LoginUtil.getLoginUser());
          biz.reviewPass(fundAjustment);
        } else {
          fundAjustment.setModiDate(new Date());
          fundAjustment.setModifier(LoginUtil.getLoginUser());
          Object purl = generatePayUrl(fundAjustment);
          if (FundPayTypeEnum.ONLINE.toString().equals(fundAjustment.getFundPayType())) {
            fundAjustment.setTransferCertificate(null);
          }
          biz.saveOrupdateEntity(fundAjustment);
          return Result.newSuccessInstance(MsgConstants.SAVE_SUECCES, purl);
        }
      }
      msg = Result.newSuccessInstance(MsgConstants.SAVE_SUECCES);
      return msg;
    } catch (Exception e) {
      e.printStackTrace();
      msg = Result.newFailInstance(MsgConstants.SAVE_FAIL + e.getMessage());
      return msg;
    }
  }

  @RequestMapping("/ajustment-findList")
  @ResponseBody
  @Json({@JField("id"), @JField("bid"), @JField("billNo"), @JField("owner.name"),
      @JField("registrant.account"), @JField("amount"), @JField("fundPayType"), @JField("state"),
      @JField("regDate"), @JField("reviewDate"), @JField("registrant.name"),
      @JField("modifier.name"), @JField("reviewer.name")})
  public Page<FundAjustment> findList(Jqgrid jqgrid) {
    try {
      SearchRule rule = new SearchRule("owner.id", SearchRuleOption.eq,
          LoginUtil.getLoginUser().getCompany().getId());
      jqgrid.addRule(rule);
      return biz.findByJqgrid(jqgrid);
    } catch (QueryException e) {
      e.printStackTrace();
    }
    return null;
  }

  @RequestMapping("/ajustment-checkShuiDan")
  @ResponseBody
  public Result checkShuiDan(String shuidan) {
    if (StringUtils.isNotEmpty(shuidan)) {
      String sql = " select 1 from T_BIZ_FUND_AJUSTMENT t where t.review_shuidan_no=:shuidan ";
      Map<String, Object> parmeters = new HashMap<>();
      parmeters.put("shuidan", shuidan);
      try {
        int count = biz.findEntityCountBySql(sql, parmeters);
        if (count == 0) {
          return Result.newSuccessInstance("{\"state\":1,\"msg\":\"\"}");
        }
      } catch (QueryException e) {
        e.printStackTrace();
      }
    }
    return Result.newFailInstance("{\"state\":0,\"msg\":\"水单号已存在!\"}");
  }


  @RequestMapping("paymentPlatform/airpay/payReturn")
  public String platformAirPayReturn(){
    return null;
  }
}
